package cn.iocoder.yudao.module.todo.service.tasks;

import cn.hutool.core.util.IdUtil;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.todo.dal.dataobject.tasksexecutors.TasksExecutorsDO;
import cn.iocoder.yudao.module.todo.dal.dataobject.tasksparticipants.TasksParticipantsDO;
import cn.iocoder.yudao.module.todo.dal.mysql.tasksexecutors.TasksExecutorsMapper;
import cn.iocoder.yudao.module.todo.dal.mysql.tasksparticipants.TasksParticipantsMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import cn.iocoder.yudao.module.todo.controller.admin.tasks.vo.*;
import cn.iocoder.yudao.module.todo.dal.dataobject.tasks.TasksDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.todo.dal.mysql.tasks.TasksMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.todo.enums.ErrorCodeConstants.*;

/**
 * 待办任务 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class TasksServiceImpl implements TasksService {

    @Resource
    private TasksMapper tasksMapper;

    @Resource
    private TasksExecutorsMapper tasksExecutorsMapper;

    @Resource
    private TasksParticipantsMapper tasksParticipantsMapper;

    @Override
    @Transactional
    public Long createTasks(TasksCreateReqVO createReqVO) {
        // 插入
        TasksDO tasksDO = BeanUtils.toBean(createReqVO, TasksDO.class);
        tasksDO.setId(IdUtil.getSnowflakeNextId());
        tasksDO.setCreator(SecurityFrameworkUtils.getLoginUserId().toString());
        TasksDO tasksDO1 = tasksMapper.selectOne(new QueryWrapper<TasksDO>().eq("source_id", tasksDO.getSourceId()).eq("system_id", tasksDO.getSystemId()));
        if (tasksDO1 != null) {
            throw exception(TASKS_EXISTS);
        }
        tasksMapper.insert(tasksDO);
        //  处理执行者集合
        List<String> executorIds = createReqVO.getExecutorIds();
        if (executorIds != null && !executorIds.isEmpty()) {
            List<TasksExecutorsDO> tasksExecutorsDOS = executorIds.stream()
                    .map(executorId -> {
                        TasksExecutorsDO tasksExecutorsDO = new TasksExecutorsDO();
                        tasksExecutorsDO.setUserId(executorId);
                        tasksExecutorsDO.setTaskId(String.valueOf(tasksDO.getId()));
                        tasksExecutorsDO.setStatus("0");
                        return tasksExecutorsDO;
                    })
                    .collect(Collectors.toList());
            tasksExecutorsMapper.insertBatch(tasksExecutorsDOS, executorIds.size());
        }

        // 处理参与者集合
        List<String> participants = createReqVO.getParticipantIds();
        if (participants == null || participants.isEmpty()) {
            participants = new ArrayList<>();
        }
        //默认待办创建者有参与者权限
        participants.add(SecurityFrameworkUtils.getLoginUserId().toString());
        List<TasksParticipantsDO> tasksParticipantsDOS = participants.stream()
                .map(participantId -> {
                    TasksParticipantsDO tasksParticipantsDO = new TasksParticipantsDO();
                    tasksParticipantsDO.setUserId(participantId);
                    tasksParticipantsDO.setTaskId(String.valueOf(tasksDO.getId()));
                    return tasksParticipantsDO;
                })
                .collect(Collectors.toList());
        tasksParticipantsMapper.insertBatch(tasksParticipantsDOS, participants.size());
        // 返回
        return tasksDO.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class) // 添加事务注解
    public void updateTasks(Long taskId, TasksSaveReqVO updateReqVO) {
        TasksDO tasksDO = tasksMapper.selectById(taskId);
        if (tasksDO == null) {
            throw exception(TASKS_NOT_EXISTS);
        }
        if (!tasksDO.getCreator().equals(SecurityFrameworkUtils.getLoginUserId().toString())) {
            throw exception(NO_TASKS_UPDATE_PERMISSION);
        }
        // 更新
        TasksDO updateObj = BeanUtils.toBean(updateReqVO, TasksDO.class);
        updateObj.setId(taskId);
        tasksMapper.updateById(updateObj);

        //  处理执行者集合
        tasksExecutorsMapper.deleteById(String.valueOf(taskId));
        List<String> executorIds = updateReqVO.getExecutorIds();
        if (executorIds != null && !executorIds.isEmpty()) {
            List<TasksExecutorsDO> tasksExecutorsDOS = executorIds.stream()
                    .map(executorId -> {
                        TasksExecutorsDO tasksExecutorsDO = new TasksExecutorsDO();
                        tasksExecutorsDO.setUserId(executorId);
                        tasksExecutorsDO.setTaskId(String.valueOf(taskId));
                        return tasksExecutorsDO;
                    })
                    .collect(Collectors.toList());
            tasksExecutorsMapper.insertBatch(tasksExecutorsDOS, executorIds.size());
        }

        // 处理参与者集合
        tasksParticipantsMapper.deleteById(String.valueOf(taskId));
        List<String> participants = updateReqVO.getParticipantIds();
        if (participants != null && !participants.isEmpty()) {
            List<TasksParticipantsDO> tasksParticipantsDOS = participants.stream()
                    .map(participantId -> {
                        TasksParticipantsDO tasksParticipantsDO = new TasksParticipantsDO();
                        tasksParticipantsDO.setUserId(participantId);
                        tasksParticipantsDO.setTaskId(String.valueOf(taskId));
                        return tasksParticipantsDO;
                    })
                    .collect(Collectors.toList());
            tasksParticipantsMapper.insertBatch(tasksParticipantsDOS, participants.size());
        }

    }

    @Override
    @Transactional
    public void completeTask(Long taskId) {
        TasksDO tasksDO = tasksMapper.selectById(taskId);
        if (tasksDO == null) {
            throw exception(TASKS_NOT_EXISTS);
        }
        if (tasksDO.getCreator().equals(SecurityFrameworkUtils.getLoginUserId().toString())) {
            tasksDO.setStatus("1");
            tasksMapper.updateById(tasksDO);
        } else {
            TasksExecutorsDO tasksExecutorsDO = tasksExecutorsMapper.selectOne(new QueryWrapper<TasksExecutorsDO>().eq("task_id", taskId).eq("user_id", SecurityFrameworkUtils.getLoginUserId().toString()));
            if (tasksExecutorsDO == null) {
                throw exception(USER_IS_NOT_A_EXECUTOR);
            }
            tasksExecutorsDO.setStatus("1");
            tasksExecutorsMapper.updateById(tasksExecutorsDO);
            Long count = tasksExecutorsMapper.selectCount(new QueryWrapper<TasksExecutorsDO>().eq("task_id", taskId).eq("status", 1));
            if (count == 0) {
                tasksDO.setStatus("1");
                tasksMapper.updateById(tasksDO);
            }
        }
    }

    @Override
    @Transactional
    public void completeTasks(List<Long> taskIds) {
        List<TasksDO> tasksDOList = tasksMapper.selectBatchIds(taskIds);
        if (tasksDOList == null || tasksDOList.isEmpty()) {
            throw exception(TASKS_NOT_EXISTS);
        }
        for (TasksDO tasksDO : tasksDOList) {
            completeTask(tasksDO.getId());
        }
    }

    @Override
    @Transactional
    public void deleteTasks(Long taskId) {
        // 检验权限
        TasksDO tasksDO = tasksMapper.selectById(taskId);
        if (tasksDO == null) {
            throw exception(TASKS_NOT_EXISTS);
        }
        if (!tasksDO.getCreator().equals(SecurityFrameworkUtils.getLoginUserId().toString())) {
            throw exception(NO_TASKS_UPDATE_PERMISSION);
        }
        // 删除
        tasksMapper.deleteById(taskId);
        tasksExecutorsMapper.deleteById(String.valueOf(taskId));
        tasksParticipantsMapper.deleteById(String.valueOf(taskId));
    }

    @Override
    public TasksDO getTasks(Long id) {
        return tasksMapper.selectById(id);
    }

    @Override
    public PageResult<TasksDO> getTasksPage(TasksPageReqVO pageReqVO) {
        // 构建关联查询条件
        MPJLambdaWrapper<TasksDO> wrapper = new MPJLambdaWrapperX<TasksDO>()
                .selectAll(TasksDO.class)
                .leftJoin(TasksExecutorsDO.class, TasksExecutorsDO::getTaskId, TasksDO::getId)
                .eq(TasksExecutorsDO::getUserId, SecurityFrameworkUtils.getLoginUserId().toString());

        // 执行关联查询
        return tasksMapper.selectJoinPage(pageReqVO, TasksDO.class, wrapper);
    }

}